(defun next-m(m d a)
  (- (* d a) m))

(defun next-d(s m d)
   (/ (- s (* m m)) d))

(defun next-a (s m d)
  (floor (/ (+ (sqrt s) m) d)))

(defun next(s &optional (vls ()) (m 0) (d 1) (a (isqrt s)))
  (let* ((nm (next-m m d a))
	 (nd (next-d s nm d))
	 (na (next-a s  nm nd)))
    (if (find (list nm nd na) vls :test #'equal) ()
	(cons  na  (next s (cons (list m d a) vls)  nm nd na)))))

(defun fractions(s)
  (loop 
;     for i from 1 to 10
     for m = 0 then (- (* d a) m)
     for d = 1 then (/ (- s (* m m)) d)
     for a = (isqrt s) then (floor (/ (+ (sqrt s) m) d))
     until (find (list m d a) values :test #'equal)
     for values = nil then (cons (list m d a) values)
     when (not (null values)) collect a ))

(defun fix-first(l)
  (if (and (= (length l) 2) (= (car l) (cadr l)))
      (cdr l)
      l))

(defun probl64()
  (loop for i in 
       (mapcar #'length 
	       (mapcar #'fix-first
		       (loop for i from 1 to 10000
			  when (not (squarep i)) 
			  collect (next i))))
     counting (oddp i)))

;(time (loop for i in (loop for i from 1 to 10000 when (not (squarep i)) collect (length (fractions i))) counting (oddp i)))